home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / oledem / oleacces.bas < prev    next >
BASIC Source File  |  1995-05-09  |  13KB  |  390 lines

  1. Option Explicit
  2.  
  3. 'Global Constants
  4.  
  5. Global Const LENGTH_FOR_SIZE = 4
  6. Global Const OBJECT_SIGNATURE = &H1C15
  7. Global Const OBJECT_HEADER_SIZE = 20
  8. Global Const CHECKSUM_SIGNITURE = &HFE05AD00
  9. Global Const CHECKSUM_STRING_SIZE = 4
  10.  
  11. 'PT : Window sizing information for object
  12. '     Used in OBJECTHEADER type
  13. Type PT
  14.     Width As Integer
  15.     Height As Integer
  16. End Type
  17.  
  18. 'OBJECTHEADER : Contains relevant information about object
  19. '
  20. Type OBJECTHEADER
  21.     Signature As Integer         'Type signiture (0x1c15)
  22.     HeaderSize As Integer        'Size of header (sizeof(struct OBJECTHEADER) + cchName + cchClass)
  23.     ObjectType As Long           'OLE Object type code (OT_STATIC, OT_LINKED, OT_EMBEDDED)
  24.     NameLen As Integer           'Count of characters in object name (CchSz(szName) + 1)
  25.     ClassLen As Integer          'Count of characters in class name (CchSz(szClass) + 1)
  26.     NameOffset As Integer        'Offset of object name in structure (sizeof(OBJECTHEADER))
  27.     ClassOffset As Integer       'Offset of class name in structure (ibName + cchName)
  28.     ObjectSize As PT             'Original size of object (see code below for value)
  29.     NameAndClass As String * 255 'Name and class of object
  30. End Type
  31.  
  32.  
  33.  
  34. 'Windows kernel function for unique temporary filename
  35. Declare Function GetTempFileName Lib "Kernel" (ByVal cDriveLetter As Integer, ByVal lpPrefixString As String, ByVal wUnique As Integer, ByVal lpTempFileName As String) As Integer
  36.  
  37. 'This DANGEROUS function allows copying data between different variable types
  38. Declare Sub hmemcpy Lib "Kernel" (dest As Any, source As Any, ByVal bytes As Long)
  39.  
  40. 'Checksum function put in DLL for speed
  41. Declare Sub ComputeCheckSum Lib "OLECS.DLL" (CheckSum As Integer, ByVal s As String, ByVal Length As Long)
  42.  
  43. 'Ole declarations
  44. 'Comment out if declared elsewhere
  45. Global Const OLE_SAVE_TO_FILE = 11
  46. Global Const OLE_READ_FROM_FILE = 12
  47. Global Const OLE_SAVE_TO_OLE1FILE = 18
  48.  
  49. Sub CopyAccess1xOleToField (OleObject As Control, FieldObject As Field)
  50.     '
  51.     ' Copies Ole object to Field Control
  52.     ' writing Access 1.x ole storage format.
  53.     ' Useful for cross compatibility with
  54.     ' Access 1.x, but saves object as Ole1.
  55.     '
  56.     ' OleObject   :   Ole2 control to save
  57.     ' FieldObject :   Database field control to write
  58.     '
  59.     Dim FileNumber As Integer
  60.     Dim FileName As String * 255
  61.     Dim OleHeaderString As String
  62.     Dim oh As OBJECTHEADER
  63.     Dim FileBuffer As String
  64.     Dim CheckSum As Integer
  65.     Dim FileLength As Long
  66.     Dim FileOffset As Long
  67.     Dim BufferLength As Integer
  68.     Dim HeaderLength As Integer
  69.     Dim DocumentClass As String
  70.     Dim DocumentName As String
  71.     Dim CheckSumString As String
  72.     Dim CheckSumCompare As String
  73.     Dim Result%
  74.     
  75.     BufferLength = 5128
  76.  
  77.     DocumentClass = OleObject.Class
  78.     DocumentName = OleObject.HostName
  79.     
  80.     'Write ole object to temporary file
  81.     'We do this first in case it fails
  82.     Result% = GetTempFileName(0, "OLE", -1, FileName)
  83.     FileNumber = FreeFile
  84.     Open FileName For Binary As FileNumber
  85.     OleObject.FileNumber = FileNumber
  86.     OleObject.Action = OLE_SAVE_TO_OLE1FILE
  87.     Close FileNumber
  88.     
  89.     'Create object header
  90.     'The extra 2 for Headersize are the null characters
  91.     oh.Signature = OBJECT_SIGNATURE
  92.     oh.HeaderSize = OBJECT_HEADER_SIZE + Len(DocumentName) + Len(DocumentClass) + 2
  93.     oh.ObjectType = OleObject.OLEType
  94.     oh.NameLen = Len(DocumentName) + 1
  95.     oh.ClassLen = Len(DocumentClass) + 1
  96.     oh.NameOffset = OBJECT_HEADER_SIZE
  97.     oh.ClassOffset = OBJECT_HEADER_SIZE + oh.NameLen
  98.     oh.ObjectSize.Width = OleObject.Width
  99.     oh.ObjectSize.Height = OleObject.Height
  100.     oh.NameAndClass = DocumentName + Chr$(0) + DocumentClass + Chr$(0)
  101.     
  102.     'Transfer this to a string
  103.     OleHeaderString = String$(oh.HeaderSize, 0)
  104.     Call hmemcpy(ByVal OleHeaderString, oh, oh.HeaderSize)
  105.  
  106.     'Write this string to Access OLE field
  107.     FieldObject.AppendChunk (OleHeaderString)
  108.  
  109.     'Initialize Checksum byte
  110.     CheckSum = 0
  111.  
  112.     'Write ole object from file to Access, calculating checksum
  113.     FileLength = FileLen(FileName)
  114.     Open FileName For Binary As FileNumber
  115.     Do While FileLength > 0
  116.         
  117.         'Get file buffer
  118.         If BufferLength > FileLength Then
  119.             BufferLength = FileLength
  120.         End If
  121.         FileBuffer = String$(BufferLength, 32)
  122.         Get FileNumber, , FileBuffer
  123.  
  124.         'Calculate checksum
  125.         Call ComputeCheckSum(CheckSum, FileBuffer, Len(FileBuffer))
  126.  
  127.         'Write this chunk to access
  128.         FieldObject.AppendChunk (FileBuffer)
  129.  
  130.         'Decrement file length
  131.         FileLength = FileLength - BufferLength
  132.  
  133.     Loop
  134.  
  135.     'Close and kill file
  136.     Close FileNumber
  137.     Kill FileName
  138.  
  139.     'Write the checksum string:
  140.     CheckSumString = String$(CHECKSUM_STRING_SIZE, 32)
  141.     Call hmemcpy(ByVal CheckSumString, CHECKSUM_SIGNITURE Or CheckSum, CHECKSUM_STRING_SIZE)
  142.     FieldObject.AppendChunk CheckSumString
  143.     
  144. End Sub
  145.  
  146. Sub CopyFieldToAccess1xOle (FieldObject As Field, OleObject As Control)
  147.     '
  148.     ' Copies Field Control to Ole Object
  149.     ' reading Access 1.x ole storage format.
  150.     ' Useful for cross compatibility with
  151.     ' Access 1.x.  You would use this
  152.     ' function to read an Ole object
  153.     ' created by Access (1.x) or CopyAccess1xOleToField.
  154.     '
  155.     ' FieldObject :  Database field control to read
  156.     ' OleObject   :  Ole2 control to load
  157.     '
  158.     Dim FileNumber As Integer
  159.     Dim FileName As String * 255
  160.     Dim OleHeaderString As String
  161.     Dim oh As OBJECTHEADER
  162.     Dim FileBuffer As String
  163.     Dim CheckSum As Integer
  164.     Dim FileLength As Long
  165.     Dim FileOffset As Long
  166.     Dim BufferLength As Integer
  167.     Dim HeaderLength As Integer
  168.     Dim DocumentName As String
  169.     Dim DocumentClass As String
  170.     Dim CheckSumString As String
  171.     Dim CheckSumCompare As String
  172.     Dim Result%
  173.             
  174.     BufferLength = 5128
  175.     
  176.     'Get first four bytes of the object to determine length of header
  177.     OleHeaderString = FieldObject.GetChunk(0, LENGTH_FOR_SIZE)
  178.     
  179.     'Copy this to oh structure
  180.     Call hmemcpy(oh, ByVal OleHeaderString, LENGTH_FOR_SIZE)
  181.     HeaderLength = oh.HeaderSize
  182.     
  183.     'Note: You could test first element of oh for
  184.     '      OBJECT_SIGNATURE here.
  185.  
  186.     'Now get all of the header
  187.     OleHeaderString = FieldObject.GetChunk(0, HeaderLength)
  188.  
  189.     'Translate this to OBJECTHEADER structure
  190.     Call hmemcpy(oh, ByVal OleHeaderString, HeaderLength)
  191.  
  192.     'Note: Now you could check variables in OBJECTHEADER structure.
  193.     '      This is what Access does to display class name without
  194.     '      loading the object into an ole container.
  195.  
  196.     'Now write the rest of the Access OLE object, minus Checksum bytes,
  197.     'to temporary file
  198.     Result% = GetTempFileName(0, "OLE", -1, FileName)
  199.     FileNumber = FreeFile
  200.     Open FileName For Binary As FreeFile
  201.  
  202.     FileLength = FieldObject.FieldSize() - HeaderLength - CHECKSUM_STRING_SIZE
  203.     FileOffset = HeaderLength
  204.  
  205.     'Reset checksum
  206.     CheckSum = 0
  207.     
  208.     'Loop through file
  209.     Do While FileLength > 0
  210.         
  211.         If BufferLength > FileLength Then
  212.             BufferLength = FileLength
  213.         End If
  214.         FileBuffer = FieldObject.GetChunk(FileOffset, BufferLength)
  215.  
  216.         'Calculate checksum
  217.         Call ComputeCheckSum(CheckSum, FileBuffer, Len(FileBuffer))
  218.  
  219.         'Write to temp file
  220.         Put FileNumber, , FileBuffer
  221.  
  222.         'Resize FileLength and FileOffset
  223.         FileLength = FileLength - BufferLength
  224.         FileOffset = FileOffset + BufferLength
  225.     
  226.     Loop
  227.  
  228.     'Get the Checksum string from Access object
  229.     CheckSumString = FieldObject.GetChunk(FileOffset, CHECKSUM_STRING_SIZE)
  230.     
  231.     'Create comparison string and compare to string from Access.
  232.     CheckSumCompare = String$(CHECKSUM_STRING_SIZE, 32)
  233.     Call hmemcpy(ByVal CheckSumCompare, CHECKSUM_SIGNITURE Or CheckSum, CHECKSUM_STRING_SIZE)
  234.     
  235.     'Now compare the strings
  236.     If CheckSumCompare <> CheckSumString Then
  237.         MsgB